home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Text Editor / Source / TextEditorPrefs.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-13  |  14.6 KB  |  586 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TextEditorPrefs.cpp
  3.  
  4.     Contains:    TextEditor Preference dialog & file functions
  5.  
  6.     Written by:    Steve Smith
  7.  
  8.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. #ifndef _COMPILERDEFS_
  12. #include "CompDefs.h"
  13. #endif
  14.  
  15. // -- OpenDoc Utilities --
  16.  
  17. #ifndef _EXCEPT_
  18. // Exceptions define several important macros (e.g. CHECKENV)
  19. // which are used in the SOM method dispatch glue. If Except.h
  20. // is not included early enough, exceptions may not be thrown
  21. // correctly when returning from a SOM method with "ev" parameter set.
  22. #include <Except.h>
  23. #endif
  24.  
  25. // --- TextEditor Includes ---
  26.  
  27. #ifndef _TEXTEDITORGLOBALS_
  28. #include "TextEditorGlobals.h"
  29. #endif
  30.  
  31. #ifndef _TEXTEDITORPREFS_
  32. #include "TextEditorPrefs.h"
  33. #endif
  34.  
  35. #ifndef _TEXTEDITORUTILS_
  36. #include "TextEditorUtils.h"
  37. #endif
  38.  
  39. #ifndef _TEXTEDITORDEF_
  40. #include "TextEditorDef.h"
  41. #endif
  42.  
  43. #ifndef _STDTEXTPROPERTIES_
  44. #include "StdTextProps.h"
  45. #endif
  46.  
  47. // --- OpenDoc Includes ---
  48.  
  49. #ifndef _ODTYPES_
  50. #include <ODTypes.h>
  51. #endif
  52.  
  53. #ifndef SOM_ODSession_xh
  54. #include <ODSessn.xh>
  55. #endif
  56.  
  57. #ifndef SOM_Module_OpenDoc_StdProps_defined
  58. #include <StdProps.xh>
  59. #endif
  60.  
  61. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  62. #include <StdTypes.xh>
  63. #endif
  64.  
  65. #ifndef _EXCEPT_
  66. #include "Except.h"
  67. #endif
  68.  
  69. #ifndef SOM_ODStorageUnit_xh
  70. #include <StorageU.xh>
  71. #endif
  72.  
  73. #ifndef SOM_ODContainer_xh
  74. #include <ODCtr.xh>
  75. #endif
  76.  
  77. #ifndef SOM_ODStorageSystem_xh
  78. #include <ODStor.xh>
  79. #endif
  80.  
  81. #ifndef SOM_ODDraft_xh
  82. #include <Draft.xh>
  83. #endif
  84.  
  85. #ifndef SOM_ODDocument_xh
  86. #include "Document.xh"
  87. #endif
  88.  
  89. #ifndef SOM_ODArbitrator_xh
  90. #include <Arbitrat.xh>
  91. #endif
  92.  
  93. #ifndef SOM_ODDispatcher_xh
  94. #include <Disptch.xh>
  95. #endif
  96.  
  97. #ifndef SOM_ODWindowState_xh
  98. #include <WinStat.xh>
  99. #endif
  100.  
  101. #ifndef SOM_Module_OpenDoc_Foci_defined
  102. #include <Foci.xh>
  103. #endif
  104.  
  105. // --- OpenDoc Utilities
  106.  
  107. #ifndef _BARRAY_
  108. #include <BArray.h>
  109. #endif
  110.  
  111. #ifndef _ODMEMORY_
  112. #include <ODMemory.h>
  113. #endif
  114.  
  115. #ifndef _USERSRCM_
  116. #include <UseRsrcM.h>
  117. #endif
  118.  
  119. #ifndef _DLOGUTIL_
  120. #include "DlogUtil.h"
  121. #endif
  122.  
  123. #ifndef _ODUTILS_
  124. #include "ODUtils.h"
  125. #endif
  126.  
  127. #ifndef _STDTYPIO_
  128. #include "StdTypIO.h"
  129. #endif
  130.  
  131. #ifndef _TEMPOBJ_
  132. #include "TempObj.h"
  133. #endif
  134.  
  135. // --- Macintosh Includes ---
  136.  
  137. #ifndef __RESOURCES__
  138. #include <Resources.h>
  139. #endif
  140.  
  141. #ifndef __DIALOGS__
  142. #include <Dialogs.h>
  143. #endif
  144.  
  145. #ifndef __WINDOWS__
  146. #include <Windows.h>
  147. #endif
  148.  
  149. #ifndef __TOOLUTILS__
  150. #include <ToolUtils.h>
  151. #endif
  152.  
  153. #ifndef mathRoutinesIncludes
  154. #include <math routines.h>
  155. #endif
  156.  
  157. #ifndef __FP__
  158. #include <fp.h>
  159. #endif
  160.  
  161. #ifndef __TEXTUTILS__
  162. #include <TextUtils.h>
  163. #endif
  164.  
  165. #ifndef __OSUTILS__
  166. #include <OSUtils.h>
  167. #endif
  168.  
  169. #ifndef __SCRIPT__
  170. #include <Script.h>
  171. #endif
  172.  
  173. #ifndef __FOLDERS__
  174. #include <Folders.h>
  175. #endif
  176.  
  177. #ifndef __FONTS__
  178. #include <Fonts.h>
  179. #endif
  180.  
  181.  
  182. #pragma segment TextEditorPreferences
  183.  
  184.  
  185. //------------------------------------------------------------------------------
  186. // ModalPreferencesDialog
  187. //------------------------------------------------------------------------------
  188.  
  189. void ModalPreferencesDialog( Environment* ev, ODFrame* frame )
  190. {
  191.     const ODUShort kFontPopup = 7;
  192.     const ODUShort kSizeField = 8;
  193.     
  194.     TempODPart part = frame->AcquirePart(ev);
  195.     ODSession* session = ODGetSession(ev, part);
  196.     
  197.     // Our About box is modal so we must request the Modal focus to prevent
  198.     // multiple modal dialogs being displayed simultaneously.
  199.     
  200.     if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fModalFocus, frame) )
  201.     {
  202.         DialogPtr dialog = kODNULL;
  203.         ODVolatile(dialog);
  204.  
  205.         CUsingLibraryResources res;
  206.  
  207.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  208.             // Dim the frontmost document window.
  209.         
  210.         TRY
  211.             short        iType;
  212.             Handle        iHandle;
  213.             Rect        iRect;
  214.             ODSShort    itemHit;
  215.             Str255        strValue;
  216.             Str255        fontStr;
  217.             ODUShort    fontSize;
  218.  
  219.             dialog = GetNewDialog(kPreferencesDialogID, kODNULL, (WindowPtr)-1L);
  220.             THROW_IF_NULL(dialog);
  221.             
  222.             // Set dialog font and other std things.
  223.             SetDialogDefaults(dialog, kDialogFontInfoID, kPrefFontIndex);
  224.             
  225.             // Read in the current "settings" from the preferences file
  226.             ReadPreferences(ev, session, fontStr, &fontSize);
  227.             
  228.             // Get a string representation of the font size and put it in the text field.
  229.             NumToString(fontSize, strValue);
  230.             
  231.             GetDialogItem(dialog, kSizeField, &iType, &iHandle, &iRect);
  232.             SetDialogItemText(iHandle, strValue);
  233.             SelectDialogItemText(dialog, kSizeField, 0, 32767);
  234.             
  235.             // Get the popup menu control.
  236.             ControlHandle popupMenu;
  237.             GetDialogItem(dialog, kFontPopup, &iType, (Handle*) &popupMenu, &iRect);
  238.             
  239.             // Find the initial item for the popup menu and set it.
  240.             {
  241.                 PopupPrivateData** privData = (PopupPrivateData**) (**popupMenu).contrlData;
  242.                 MenuHandle privMenu = (**privData).mHandle;
  243.     
  244.                 short initialItem = 0;
  245.                 for (int i = 1; i <= CountMItems(privMenu); i++)
  246.                 {
  247.                     Str255 menuItem;
  248.                     GetMenuItemText(privMenu, i, menuItem);
  249.                     
  250.                     if ( IUEqualString(fontStr, menuItem) == 0 )
  251.                     {
  252.                         initialItem = i;
  253.                         break;
  254.                     }
  255.                 }
  256.                 
  257.                 SetControlValue(popupMenu, initialItem);
  258.             }
  259.             
  260.             // Show the window and handle events in it.
  261.             ShowWindow(dialog);
  262.             ModalFilterUPP otherDialogProc = NewModalFilterProc(OtherDialogFilter);
  263.             
  264.             do
  265.             {
  266.                 ModalDialog(otherDialogProc, &itemHit);
  267.             }
  268.             while (itemHit != ok && itemHit != cancel);
  269.     
  270.             DisposeRoutineDescriptor(otherDialogProc);
  271.             
  272.             // If OK was hit, handle the change.
  273.             if ( itemHit == ok )
  274.             {
  275.                 // Get the font name.
  276.                 short controlValue = GetControlValue(popupMenu);
  277.                 PopupPrivateData** privData = (PopupPrivateData**) (**popupMenu).contrlData;
  278.                 MenuHandle privMenu = (**privData).mHandle;
  279.                 
  280.                 GetMenuItemText(privMenu, controlValue, fontStr);
  281.                 
  282.                 // Get the font size (and make sure it's sane).
  283.                 GetDialogItem(dialog, kSizeField, &iType, &iHandle, &iRect);
  284.                 GetDialogItemText(iHandle, strValue);
  285.                 
  286.                 long value = 0;
  287.                 if ( strValue[0] > 0 )
  288.                     StringToNum(strValue, &value);
  289.                 
  290.                 fontSize = (ODUShort) value;
  291.  
  292.                 if ( value > 127 )
  293.                     fontSize = 127;
  294.                 
  295.                 // Write these to the preferences file.
  296.                 WritePreferences(ev, session, fontStr, &fontSize);
  297.             }
  298.             
  299.         CATCH_ALL
  300.             // Cleanup the dialog.
  301.             if (dialog != kODNULL)
  302.                 DisposeDialog(dialog);
  303.  
  304.             // Inform the Arbitrator that we no longer require the Modal focus.
  305.             session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, frame);
  306.  
  307.             // Hilite the frontmost document window.
  308.             session->GetWindowState(ev)->ActivateFrontWindows(ev);
  309.             
  310.             RERAISE;
  311.         ENDTRY
  312.         
  313.         // Cleanup the dialog.
  314.         DisposeDialog(dialog);
  315.  
  316.         session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, frame);
  317.             // Inform the Arbitrator that we no longer require the Modal focus.
  318.         session->GetWindowState(ev)->ActivateFrontWindows(ev);
  319.             // Hilite the frontmost document window.
  320.     }
  321. }
  322.  
  323. //------------------------------------------------------------------------------
  324. // GetPreferences
  325. //------------------------------------------------------------------------------
  326.  
  327. void GetPreferences( Environment* ev, FSSpec* prefFile, 
  328.                      ODBoolean* newFile )
  329. {
  330.     *newFile = kODFalse;
  331.     
  332.     ODGetIndString(prefFile->name, kRuntimeStringsID, kPrefFileNameStrIndex);
  333.     THROW_IF_ERROR(FindFolder(kOnSystemDisk, kPreferencesFolderType, 
  334.                               kDontCreateFolder,
  335.                               &prefFile->vRefNum, &prefFile->parID));
  336.     
  337.     FInfo fInfo;
  338.     OSErr error = FSpGetFInfo(prefFile, &fInfo);
  339.     
  340.     if ( error == fnfErr)
  341.     {
  342.         THROW_IF_ERROR(FSpCreate(prefFile, kTextEditorEditorOSType, 
  343.                                  kPreferencesFolderType,
  344.                                  gGlobals->fEditorsScript));
  345.         
  346.         *newFile = kODTrue;
  347.     }
  348.     else
  349.     {
  350.         THROW_IF_ERROR(error);
  351.     }
  352. }
  353.  
  354. //------------------------------------------------------------------------------
  355. // GetPrefStorageUnit
  356. //------------------------------------------------------------------------------
  357.  
  358. ODBoolean GetPrefStorageUnit( Environment* ev, ODSession* session, 
  359.                               ODStorageUnit** prefSU )
  360. {
  361.     ODBoolean result = kODTrue;
  362.  
  363.     FSSpec prefFile;
  364.     ODVolatile(prefFile);
  365.     
  366.     prefFile.vRefNum = 0;
  367.     prefFile.parID = 0;
  368.  
  369.     TRY
  370.         ODBoolean newFile;
  371.         GetPreferences(ev, &prefFile, &newFile);
  372.         
  373.         // Open or create the preferences file.
  374.         ODStorageSystem* storage = session->GetStorageSystem(ev);
  375.  
  376.         TempODByteArray id = CreateByteArray(&prefFile, sizeof(FSSpec));
  377.         
  378.         TempODContainer container = kODNULL;
  379.         
  380.         if ( newFile )
  381.             container = storage->CreateContainer(ev, kODDefaultFileContainer, id);
  382.         else
  383.             container = storage->AcquireContainer(ev, kODDefaultFileContainer, id);
  384.         
  385.         // Get the document, draft, and draft props.
  386.         TempODDocument document = container->AcquireDocument(ev, kODDefaultDocument);
  387.         TempODDraft draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  388.         TempODStorageUnit draftPropsSU = draft->AcquireDraftProperties(ev);    
  389.         TempODStorageUnit su = kODNULL;
  390.         
  391.         // Get the preferences storage unit.  If we're making a new file, set it up.
  392.         if ( ODSUExistsThenFocus(ev, draftPropsSU, kTextEditorPreferences, kODStrongStorageUnitRef) )
  393.         {
  394.             ODStorageUnitRef suRef;
  395.             StorageUnitGetValue(draftPropsSU, ev, sizeof(ODStorageUnitRef), &suRef);
  396.             
  397.             su = draft->AcquireStorageUnit(ev, draftPropsSU->GetIDFromStorageUnitRef(ev, suRef));
  398.         }
  399.         else
  400.         {
  401.             // Make sure we have an entry in the draft properties of the prefs file (create
  402.             // one if we don't).
  403.             if ( !draftPropsSU->Exists(ev, kTextEditorPreferences, kODNULL, 0) )
  404.                 draftPropsSU->AddProperty(ev, kTextEditorPreferences);
  405.             else
  406.                 draftPropsSU->Focus(ev, kTextEditorPreferences, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  407.             if ( !ODSUExistsThenFocus(ev, draftPropsSU, kTextEditorPreferences, kODStrongStorageUnitRef) )
  408.                 draftPropsSU->AddValue(ev, kODStrongStorageUnitRef);
  409.  
  410.             // Create a storage unit for our preferences.
  411.             su = draft->CreateStorageUnit(ev);
  412.             
  413.             // Write a reference to it in the draft properties.
  414.             ODStorageUnitRef suRef;
  415.             draftPropsSU->GetStrongStorageUnitRef(ev, su->GetID(ev), suRef);
  416.             StorageUnitSetValue(draftPropsSU, ev, sizeof(ODStorageUnitRef), suRef);
  417.             
  418.             // Write out the changes to the draft.
  419.             draft->Externalize(ev);
  420.         }
  421.         
  422.         *prefSU = su.DontRelease();
  423.         
  424.         // We need to keep a reference to the draft, document, and container
  425.         // for later release if everything else succeeded.
  426.         draft.DontRelease();
  427.         document.DontRelease();
  428.         container.DontRelease();
  429.  
  430.     CATCH_ALL
  431.         // Something bad happened when trying to open the preferences file.
  432.         // we will try to delete the file so that it can be recreated in the
  433.         // future and won't be bad forever.
  434.         // NOTE: We probably want to alert the user to this fact.  This is
  435.         // left as an exercise for the reader, however.  We don't have that
  436.         // much stuff in our preferences and it's pretty easy to fix, so we
  437.         // won't tell the user.
  438.         
  439.         if ( prefFile.vRefNum != 0 && prefFile.parID != 0 )
  440.         {
  441.             FInfo fInfo;
  442.             OSErr error = FSpGetFInfo(&prefFile, &fInfo);
  443.             if ( error == noErr)
  444.                 (void) FSpDelete(&prefFile);
  445.         }
  446.         
  447.         result = kODFalse;
  448.     ENDTRY
  449.  
  450.     return result;    
  451. }
  452.  
  453. //------------------------------------------------------------------------------
  454. // ClosePreferences
  455. //------------------------------------------------------------------------------
  456.  
  457. void ClosePreferences( Environment* ev, ODStorageUnit* prefSU )
  458. {
  459.     // We put these in Temp's in order to release them (since they
  460.     // were acquired in GetPrefStorageUnit).  We need to use Temps
  461.     // so that they'll be released even if Externalize fails.
  462.     // The order they are released is important, so we create them 
  463.     // (on the stack) in the reverse order.  This way, they will be 
  464.     // released in the order: draft, document, container.
  465.     
  466.     TempODContainer    container = kODNULL;
  467.     TempODDocument    document  = kODNULL;
  468.     TempODDraft        draft     = kODNULL;
  469.     
  470.     draft        = prefSU->GetDraft(ev);
  471.     document    = draft->GetDocument(ev);
  472.     container    = document->GetContainer(ev);
  473.     
  474.     // Release our storage unit.
  475.     ODSafeReleaseObject(prefSU);
  476.     
  477.     // Update the draft and storage units.
  478.     draft->Externalize(ev);
  479. }
  480.  
  481. //------------------------------------------------------------------------------
  482. // ReadPreferences
  483. //------------------------------------------------------------------------------
  484.  
  485. void ReadPreferences( Environment* ev, ODSession* session, 
  486.                       StringPtr fontName, ODUShort* fontSize )
  487. {
  488.     long result = GetScriptVariable(smSystemScript, smScriptAppFondSize);
  489.     ODSShort defaultFont = HiWord(result);
  490.     ODSShort defaultSize = LoWord(result);
  491.     
  492.     ODStorageUnit* prefSU;
  493.     if ( GetPrefStorageUnit(ev, session, &prefSU) )
  494.     {
  495.         TRY
  496.             // Get the size from the default font size property.
  497.             if ( prefSU->Exists(ev, kStdProp_DefaultFontSize, kODUShort, 0) )
  498.                 *fontSize = ODGetUShortProp(ev, prefSU, kStdProp_DefaultFontSize, kODUShort);
  499.             else
  500.                 *fontSize = defaultSize;
  501.             
  502.             TempODIText intlFontName = kODNULL;
  503.             if ( prefSU->Exists(ev, kStdProp_DefaultFont, kODMacIText, 0) )
  504.                 intlFontName = ODGetITextProp(ev, prefSU, kStdProp_DefaultFont, 
  505.                                               kODMacIText, kODNULL);
  506.             
  507.             if ( intlFontName == kODNULL || GetITextStringLength(intlFontName) == 0 )
  508.                 GetFontName(defaultFont, fontName);
  509.             else
  510.                 (void) GetITextPString(intlFontName, fontName);
  511.  
  512.         CATCH_ALL
  513.             ClosePreferences(ev, prefSU);
  514.             RERAISE;
  515.         ENDTRY
  516.         
  517.         ClosePreferences(ev, prefSU);
  518.         
  519.         // Validate preference values.
  520.         ODBoolean updatePrefs = kODFalse;
  521.         
  522.         if ( *fontSize > 127 || *fontSize <= 0 )
  523.         {
  524.             *fontSize = defaultSize;
  525.             updatePrefs = kODTrue;
  526.         }
  527.         
  528.         ODSShort fontNum;
  529.         GetFNum(fontName, &fontNum);
  530.         
  531.         if ( fontNum == 0 )
  532.         {
  533.             // 0 means either the font they want is the system font or that 
  534.             // the font was not available.  Determine which case this is by
  535.             // checking the font name of the system font (e.g. "Chicago")
  536.             // against the name they were looking for.
  537.             
  538.             Str255 systemFontName;
  539.             GetFontName(0, systemFontName);
  540.             
  541.             if ( IdenticalString(systemFontName, fontName, kODNULL) != 0 )
  542.             {
  543.                 // They were looking for a font other than the system font,
  544.                 // but it wasn't available, so give them this script's default 
  545.                 // font.
  546.                 GetFontName(defaultFont, fontName);
  547.                 updatePrefs = kODTrue;
  548.             }
  549.         }
  550.  
  551.         // Write the udpated values, if necessary.
  552.         if ( updatePrefs )
  553.             WritePreferences(ev, session, fontName, fontSize);
  554.     }
  555.     else
  556.     {
  557.         GetFontName(defaultFont, fontName);
  558.         *fontSize = defaultSize;
  559.     }
  560. }
  561.  
  562. //------------------------------------------------------------------------------
  563. // WritePreferences
  564. //------------------------------------------------------------------------------
  565.  
  566. void WritePreferences( Environment* ev, ODSession* session, 
  567.                        StringPtr fontName, ODUShort* fontSize )
  568. {
  569.     ODStorageUnit* prefSU;
  570.     if ( GetPrefStorageUnit(ev, session, &prefSU) )
  571.     {
  572.         TRY
  573.             TempODIText intlFontName = CreateITextPString(smRoman, langEnglish, fontName);
  574.             
  575.             ODSetITextProp(ev, prefSU, kStdProp_DefaultFont, kODMacIText, intlFontName);
  576.             ODSetUShortProp(ev, prefSU, kStdProp_DefaultFontSize, kODUShort, *fontSize);
  577.         CATCH_ALL
  578.             ClosePreferences(ev, prefSU);
  579.             RERAISE;
  580.         ENDTRY
  581.         
  582.         ClosePreferences(ev, prefSU);
  583.     }
  584. }
  585.  
  586.